package com.test.controller;

import com.test.GadmQuery;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 地理空间查询REST控制器
 * 提供高性能的坐标到地址转换API
 */
@RestController
@RequestMapping("/api/geo")
@CrossOrigin(origins = "*") // 允许跨域访问
public class GeoQueryController {

    private static final Logger logger = LoggerFactory.getLogger(GeoQueryController.class);
    private static final ExecutorService executorService = Executors.newFixedThreadPool(
            Runtime.getRuntime().availableProcessors() * 4
    );

    /**
     * 获取完整地址信息
     * 使用多级缓存提高响应速度
     * 
     * @param lon 经度
     * @param lat 纬度
     * @return 包含地址信息的响应
     */
    @GetMapping("/address")
    @Cacheable(value = "geoAddresses", key = "#lon + ',' + #lat")
    public ResponseEntity<Map<String, Object>> getAddress(
            @RequestParam double lon, 
            @RequestParam double lat) {
        
        try {
            long startTime = System.currentTimeMillis();
            
            // 参数验证
            if (lon < -180 || lon > 180 || lat < -90 || lat > 90) {
                return ResponseEntity.badRequest().body(Map.of(
                        "error", "坐标参数无效",
                        "message", "经度范围: -180 到 180, 纬度范围: -90 到 90"
                ));
            }
            
            // 使用CompletableFuture进行异步处理
            CompletableFuture<String> addressFuture = CompletableFuture.supplyAsync(() -> {
                try {
                    return GadmQuery.getInstance().generateFullAddress(lon, lat);
                } catch (Exception e) {
                    logger.error("地址查询失败: {}", e.getMessage(), e);
                    throw new RuntimeException("地址查询服务异常", e);
                }
            }, executorService);
            
            // 使用CompletableFuture进行异步处理
            CompletableFuture<Map<Integer, Map<String, String>>> detailsFuture = CompletableFuture.supplyAsync(() -> {
                try {
                    return GadmQuery.getInstance().queryAddress(lon, lat);
                } catch (Exception e) {
                    logger.error("详细信息查询失败: {}", e.getMessage(), e);
                    throw new RuntimeException("详细信息查询服务异常", e);
                }
            }, executorService);
            
            // 等待两个异步任务完成
            String fullAddress = addressFuture.join();
            Map<Integer, Map<String, String>> detailedInfo = detailsFuture.join();
            
            long endTime = System.currentTimeMillis();
            
            // 构建响应
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("coordinates", Map.of("lon", lon, "lat", lat));
            response.put("fullAddress", fullAddress);
            response.put("detailedInfo", detailedInfo);
            response.put("processingTimeMs", endTime - startTime);
            
            logger.debug("坐标查询成功: lon={}, lat={}, 耗时={}ms", lon, lat, (endTime - startTime));
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            logger.error("查询坐标 [{}, {}] 时发生错误: {}", lon, lat, e.getMessage(), e);
            return ResponseEntity.status(500).body(Map.of(
                    "success", false,
                    "error", "Internal Server Error",
                    "message", "服务器处理请求时发生错误"
            ));
        }
    }
    
    /**
     * 健康检查端点
     */
    @GetMapping("/health")
    public ResponseEntity<Map<String, Object>> healthCheck() {
        Map<String, Object> response = new HashMap<>();
        response.put("status", "UP");
        response.put("service", "GeoQuery Service");
        return ResponseEntity.ok(response);
    }
    
    /**
     * 性能测试端点 - 仅用于测试，生产环境应移除
     */
    @GetMapping("/benchmark")
    public ResponseEntity<Map<String, Object>> benchmark(
            @RequestParam(defaultValue = "1000") int iterations) {
        
        try {
            long totalTime = 0;
            double lon = 101.6869; // 测试坐标
            double lat = 3.1390;
            
            logger.info("开始性能测试，执行{}次查询", iterations);
            
            for (int i = 0; i < iterations; i++) {
                long startTime = System.currentTimeMillis();
                GadmQuery.getInstance().generateFullAddress(lon, lat);
                long endTime = System.currentTimeMillis();
                totalTime += (endTime - startTime);
            }
            
            double avgTime = (double) totalTime / iterations;
            double qps = 1000.0 / avgTime;
            
            Map<String, Object> result = new HashMap<>();
            result.put("iterations", iterations);
            result.put("totalTimeMs", totalTime);
            result.put("avgTimePerQueryMs", avgTime);
            result.put("estimatedQPS", qps);
            result.put("maxExpectedQPS", qps * Runtime.getRuntime().availableProcessors());
            
            logger.info("性能测试完成: {}次查询, 总耗时{}ms, 平均{:.2f}ms/次, 预估QPS: {:.2f}", 
                    iterations, totalTime, avgTime, qps);
            
            return ResponseEntity.ok(result);
            
        } catch (Exception e) {
            logger.error("性能测试失败: {}", e.getMessage(), e);
            return ResponseEntity.status(500).body(Map.of(
                    "error", "性能测试失败",
                    "message", e.getMessage()
            ));
        }
    }
}